<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * this class user to do operations related to user.
 *
 * @author jianfeng
 */
class BARoleCooker extends BAEventCooker {

    const Role_Type_Customer = 'customerRole';
    const Role_Type_Admin = 'adminRole';
    const Role_Type_Member = 'memberRole';

    public static function getAllAppRoleData($format = 'string', $data = null) {
        $app = Blyn::app()->getActiveApp();
        $appName = $app->getName();
        $spaceConn = new BUISpaceConn();
        $relatedSpaceView = $spaceConn->getSpaceRelationshipList();
        $spaceAppRoles = array();
        $roles = $app->getRoles();
        foreach ($relatedSpaceView as $list) {
            $spaceId = $list->getItem('spaceId')->getValue();
            $space = new BSpace($spaceId);
            $spaceName = $space->getName();
            $roles += $app->getRoles(array('spaceId' => $spaceId));
        }
        foreach ($roles as $id => $role) {
            $spaceId = $role->spaceId;
            $space = new BSpace($spaceId);
            $spaceName = $space->getName();
            if ($format == 'string') {
                $spaceAppRoles[$id] = $spaceName . '|' . $appName . '::' . $this->getRoleAliasByFullName($role->getFullName());
            }
        }
        return $spaceAppRoles;
    }

    public static function getRoleAliasByFullName($roleFullName) {
        $aliasTable = new BSheet('roleAlias');
        $list = $aliasTable->getList(array('itemData' => array('roleFullName' => $roleFullName)));
        if ($list) {
            return $list->getItem('roleAlias')->getValue();
        } else {
            if (preg_match("/(app_customer)$/", $roleFullName)) {
                $aliasTable->addList(array('roleFullName' => $roleFullName, 'roleAlias' => '基本客户'));
            }
            if (preg_match("/(app_member)$/", $roleFullName)) {
                $aliasTable->addList(array('roleFullName' => $roleFullName, 'roleAlias' => '机构成员'));
            }
            if (preg_match("/(app_admin)$/", $roleFullName)) {
                $aliasTable->addList(array('roleFullName' => $roleFullName, 'roleAlias' => '系统管理员'));
            }
            $list = $aliasTable->getList(array('itemData' => array('roleFullName' => $roleFullName)));
        }
        //FIND AGAIN
        $list = $aliasTable->getList(array('itemData' => array('roleFullName' => $roleFullName)));
        if ($list) {
            return $list->getItem('roleAlias')->getValue();
        }
        return $roleFullName;
    }

    public function addRoleAlias($alias, $roleFullName) {

        $roleAliasTable = new BSheet('roleAlias');

        if ($roleFullName != NULL && $alias !== NULL) {
            $list = $roleAliasTable->getNewList();
            $list->addItems(array('roleAlias' => $alias, 'roleFullName' => $roleFullName));
        }
    }

    public static function getAllSpaceRoleData($roleType = 'customer', $format = 'nameList', $spaceData = null) {

        $space = NULL;
        if ($spaceData != NULL) {
            $spaceCooker = new BSpaceCooker();
            $space = $spaceCooker->getSpace($spaceData);
        } else {
            $space = Blyn::app()->getActiveSpace();
        }

        $rootRole = $space->getSpaceEngine()->getRole(BRole::Role_App_Root);
        $memberRole = $space->getSpaceEngine()->getRole(BRole::Role_App_Member);
        $customerRole = $space->getSpaceEngine()->getRole(BRole::Role_App_customer);
        $adminRole = $space->getSpaceEngine()->getRole(BRole::Role_App_Admin);

        $spaceMemberRoles = array();
        $spaceMemberRoles[$memberRole->getId()] = $memberRole;
        $spaceAdminRoles = array();
        $spaceAdminRoles[$adminRole->getId()] = $adminRole;
        $spaceCustomerRoles = array();
        $spaceCustomerRoles[$customerRole->getId()] = $customerRole;

        $spaceMemberRoles += $memberRole->getChildren(NULL, TRUE);
        $spaceCustomerRoles += $customerRole->getChildren(NULL, TRUE);
        $spaceAdminRoles += $adminRole->getChildren(NULL, TRUE);
        $spaceRoles = $rootRole->getChildren(NULL, TRUE);

        if ($format == NULL) {
            if ($roleType == 'customer') {
                return $spaceCustomerRoles;
            }
            if ($roleType == 'member') {
                return $spaceMemberRoles;
            }
            if ($roleType == 'admin') {
                return $spaceAdminRoles;
            }
            if ($roleType == NULL) {
                return array(
                    'memberRoleData' => $spaceMemberRoles,
                    'customerRoleData' => $spaceCustomerRoles,
                    'adminRoleData' => $spaceAdminRoles
                );
            }
        }

        if (strtolower($format) == 'allroles' || strtolower($format) == 'objectlist') {
            return $spaceRoles;
        }

        if (strtolower($format) == 'namelist') {
            $data = array();
            $adminRoleData = array();
            $memberRoleData = array();
            $customerRoleData = array();

            //first add space role into list
            $adminRoleData[$adminRole->getId()] = 'BSpaceEngine::' . $adminRole->getName();
            $memberRoleData[$memberRole->getId()] = 'BSpaceEngine::' . $memberRole->getName();
            $customerRoleData[$customerRole->getId()] = 'BSpaceEngine::' . $customerRole->getName();

            foreach ($spaceAdminRoles as $id => $role) {
                $appClass = 'BApp';
                $appId = $role->appId;
                if (is_numeric($appId) && $appId > 0) {
                    $app = BApp::getAppById($appId);
                    $appClass = get_class($app);
                }
                $adminRoleData[$id] = $appClass . '::' . $role->getName();
            }
            $data['adminRoleData'] = $adminRoleData;
            if (strtolower($roleType) == 'admin') {
                return $adminRoleData;
            }
            foreach ($spaceMemberRoles as $id => $role) {
                $appClass = 'BApp';
                $appId = $role->appId;
                if (is_numeric($appId) && $appId > 0) {
                    $app = BApp::getAppById($appId);
                    $appClass = get_class($app);
                }
                $memberRoleData[$id] = $appClass . '::' . $role->getName();
            }
            $data['memberRoleData'] = $memberRoleData;
            if (strtolower($roleType) == 'member') {
                return $memberRoleData;
            }
            foreach ($spaceCustomerRoles as $id => $role) {
                $appClass = 'BApp';
                $appId = $role->appId;
                if (is_numeric($appId) && $appId > 0) {
                    $app = BApp::getAppById($appId);
                    $appClass = get_class($app);
                }
                $customerRoleData[$id] = $appClass . '::' . $role->getName();
            }
            $data['customerRoleData'] = $customerRoleData;
            if (strtolower($roleType) == 'customer') {
                return $customerRoleData;
            }

            //if not specify role type
            return $data;
        }
    }

    public static function getSpaceCustomerRole($space = NULL, $data = NULL) {
        if (!$space instanceof BSpace)
            $space = Blyn::app()->getActiveSpace();
        return $space->getSpaceEngine()->getRole(BRole::Role_App_customer);
    }

    public static function getSpaceMemberRole($space = NULL, $data = NULL) {
        if (!$space instanceof BSpace)
            $space = Blyn::app()->getActiveSpace();
        return $space->getSpaceEngine()->getRole(BRole::Role_App_Member);
    }

    public static function getSpaceAdminRole($space = NULL, $data = NULL) {
        if (!$space instanceof BSpace)
            $space = Blyn::app()->getActiveSpace();
        return $space->getSpaceEngine()->getRole(BRole::Role_App_Admin);
    }

    public static function getAllRole($data = NULL) {
        $role = BRole::find(BRole::All_Roles);
        return $role;
    }

    public static function getAllUserRoles($recursive = FALSE, $user = NULL, $roleType = 'all') {

        if ($user == NULL) {
            $user = Blyn::app()->getCurrentUser();
        } else {
            if (is_numeric($user)) {
                $user = new BUser($user);
            }
        }

        $userRoles = $user->getCache('userRoles_' . $recursive);
        //$userRoles = NULL;

        if ($userRoles == NULL) {

            $userRoles = BRole::findUserRoles($user, NULL, $recursive);

            //2分钟才更新一次用户角色
            $user->setCache('userRoles_' . $recursive, $userRoles, 2 * 60);
        }

        if ($roleType == NULL) {
            $roleType = 'all';
        }

        $roleType = strtolower($roleType);
        if ($roleType == 'all') {
            return $userRoles;
        }
        if ($roleType == 'customer') {
            $customerRole = $this->getRole('customerRole');
            $roleData = array();
            foreach ($userRoles as $id => $role) {
                
            }
        }

        //return $userRoles;
    }

    public function getAllSpaceUsers() {
        $spaceRoles = $this->getAllSpaceRoleData(NULL, 'allRoles');
        $model = new BMRoleUser();

        $sql = 'select * from bln_role_user where ';

        $i = 0;
        $count = count($spaceRoles);
        foreach ($spaceRoles as $id => $role) {
            if ($i == 0) {
                $sql .= '(role_id = ' . $id;
            } else if ($i == $count - 1) {
                $sql .= ' or role_id = ' . $id . ')';
            } else {
                $sql .= ' or role_id=' . $id;
            }
            $i++;
        }

        $rows = $model->findAllBySql($sql);

        $users = array();

        foreach ($rows as $id => $row) {
            $user[$row->user_id] = new BUser($row->user_id);
        }

        return $users;
    }

    public function getAllSpaceUserWithRole() {
        $spaceRoles = $this->getAllSpaceRoleData(NULL, 'allRoles');
        $model = new BMRoleUser();

        $sql = 'select * from bln_role_user where ';

        $i = 0;
        $count = count($spaceRoles);
        foreach ($spaceRoles as $id => $role) {
            if ($i == 0) {
                $sql .= '(role_id = ' . $id;
            } else if ($i == $count - 1) {
                $sql .= ' or role_id = ' . $id . ')';
            } else {
                $sql .= ' or role_id=' . $id;
            }
            $i++;
        }

        $sql.=' order by user_id';

        $rows = $model->findAllBySql($sql);

        $userRoleList = array();

        foreach ($rows as $id => $row) {
            $userRole = array();
            $userRole['userId'] = $row->user_id;
            $userRole['roleId'] = $row->role_id;
            array_push($userRoleList, $userRole);
        }

        return $userRoleList;
    }

    public function addRoleEvent($roleId, $eventId, $data = NULL) {
        $roleEventTable = $this->getRoleEventTable();
        $list = $roleEventTable->getList(array('itemData' => array('roleId' => $roleId, 'eventId' => $eventId)));
        if ($list == NULL) {
            $itemData = array('roleId' => $roleId, 'eventId' => $eventId);
            $eventCooker = new BAEventCooker();
            $event = $eventCooker->getEvent($eventId);
            $eventType = $this->getEventTypeByEvent($event);
            if ($eventType != NULL) {
                $itemData['eventTypeId'] = $eventType->getId();
            }
            if (is_array($data)) {
                $itemData+=$data;
            }
            $list = $roleEventTable->addList($itemData);
        } else {
            if (is_array($data)) {
                $list->addItems($data);
            }
        }
        return $list;
    }

    public function getUserEventList($parentRole = NULL) {
        //$eventList = $this->getEventView();

        $roleEventTable = $this->getRoleEventTable();
        $eventTable = new BAEventSheet();

        $userRoles = self::getAllUserRoles(TRUE);

        $roleIdList = array();

        foreach ($userRoles as $id => $role) {
            array_push($roleIdList, $id);
        }

        $view = $roleEventTable->getView(array('itemData' => array('roleId' =>
                array('or' => $roleIdList)
        )));

        if ($parentRole != NULL) {
            $parentRole = $this->getRole($parentRole);
            $retView = array();
            foreach ($view as $id => $list) {
                $listData = $list->getItemsInArray();
                $roleId = $listData['roleId'];
                $role = new BRole($roleId);
                if ($role->isChildOf($parentRole)) {
                    $retView[$id] = $list;
                }
            }
            return $retView;
        }

        return $view;
    }

    public function getCurrentRole() {
        $roleId = $this->activeLink->getLinkVariable('roleId');
        if (is_numeric($roleId) && $roleId > 0) {
            Blyn::app()->getActiveOperation()->addContextVariable('roleId', $roleId);
        } else {
            $roleId = Blyn::app()->getActiveOperation()->getContextVariable('roleId');
        }
        return new BRole($roleId);
    }

    public function getRoleEventList($roleData, $eventData = NULL) {

        $roleId = NULL;
        $itemData = array();
        if (is_numeric($roleData) && $roleData > 0) {
            $roleId = $roleData;
        }
        if ($roleData instanceof BRole) {
            $roleId = $roleData->getId();
        }

        if ($roleId != NULL) {
            $itemData['roleId'] = $roleId;
        }

        if ($eventData != NULL) {
            if (is_numeric($eventData)) {
                $itemData['eventId'] = $eventData;
            }
            if ($eventData instanceof BEntity) {
                $itemData['eventId'] = $eventData->getId();
            }
        }

        $roleEventTable = $this->getRoleEventTable();
        return $roleEventTable->getView(array('itemData' => $itemData));
    }

    public function getRoleEvent($roleData, $eventData = NULL) {
        $view = $this->getRoleEventList($roleData, $eventData);
        if ($view != NULL) {
            return reset($view);
        }

        return FALSE;
    }

    public function getRoleEventById($id) {
        $table = $this->getRoleEventTable();
        return $table->getListById($id);
    }

    public function getRoleEventTable() {
        return new BAEventSheet(NULL, 'roleEvent');
    }

    public function getRole($roleData, $spaceData = NULL) {
        if (is_numeric($roleData)) {
            $roleId = $roleData;
            return new BRole($roleId);
        }

        $space = Blyn::app()->getActiveSpace();
        if ($spaceData != NULL) {
            if (is_numeric($spaceData)) {
                $space = new BSpace($spaceData);
            }
            if ($spaceData instanceof BSpace) {
                $space = $spaceData;
            }
        }
        if (is_string($roleData)) {
            if ($roleData == BRole::Role_Space_customer) {
                return $space->getSpaceEngine()->getRole(BRole::Role_Space_customer);
            }
            if ($roleData == BRole::Role_Space_Admin) {
                return $space->getSpaceEngine()->getRole(BRole::Role_Space_Admin);
            }
            if ($roleData == BRole::Role_Space_Member) {
                return $space->getSpaceEngine()->getRole(BRole::Role_Space_Member);
            }
            if ($roleData == BRole::Role_App_Admin) {
                return Blyn::app()->getActiveApp()->getRole(BRole::Role_App_Admin);
            }
            if ($roleData == BRole::Role_App_Member) {
                return Blyn::app()->getActiveApp()->getRole(BRole::Role_App_Member);
            }
            if ($roleData == BRole::Role_App_customer) {
                return Blyn::app()->getActiveApp()->getRole(BRole::Role_App_customer);
            }
        }

        if (is_array($roleData)) {
            $roleName = key($roleData);
            if (isset($roleData['name'])) {
                $roleName = $roleData['name'];
            }
            if (isset($roleData['roleName'])) {
                $roleName = $roleData['roleName'];
            }
            if (isset($roleData['role'])) {
                $roleName = $roleData['role'];
            }
            if ($roleName == BRole::Role_Space_customer) {
                return Blyn::app()->getActiveSpace()->getSpaceEngine()->getRole(BRole::Role_Space_customer);
            }
            if ($roleName == BRole::Role_Space_Admin) {
                return Blyn::app()->getActiveSpace()->getSpaceEngine()->getRole(BRole::Role_Space_Admin);
            }
            if ($roleName == BRole::Role_Space_Member) {
                return Blyn::app()->getActiveSpace()->getSpaceEngine()->getRole(BRole::Role_Space_Member);
            }
            if ($roleName == BRole::Role_App_Admin) {
                return Blyn::app()->getActiveApp()->getRole(BRole::Role_App_Admin);
            }
            if ($roleName == BRole::Role_App_Member) {
                return Blyn::app()->getActiveApp()->getRole(BRole::Role_App_Member);
            }
            if ($roleName == BRole::Role_App_customer) {
                return Blyn::app()->getActiveApp()->getRole(BRole::Role_App_customer);
            }
        }
    }

    /**
     */
    public function onShowSpaceRoleList() {

        $roleListData = self::getAllSpaceRoleData(FALSE, NULL);

        $this->updateControl->addRenderView('spaceRoleList', 'spaceRoleList', array('spaceRoleData' => $roleListData));
    }

    public function onShowAddChildRole() {

        $parentRoleId = $this->activeLink->getLinkVariable('roleId');

        $this->updateControl->addRenderView('addChildRole', 'addChildRole', array('parentRoleId' => $parentRoleId));
    }

    public function onShowApplyRole() {
        
    }

    /*
     * use to show admin role, this is 
     */

    public function onShowAddSpaceRole() {
        $roleListData = self::getAllSpaceRoleData(FALSE);

        $this->updateControl->addRenderView('addSpaceRole', 'addSpaceRole', array('spaceRoleData' => $roleListData));
    }

    public function onShowApproveRole() {
        
    }

    public function onAddChildRole() {
        $parentRoleId = $this->activeLink->getLinkVariable('parentRoleId');

        $postManage = new BPostManager();
        $postData = $postManage->parsedModelData();
        $mediaList = $postManage->populateMediaListFromPostData($postData, 'addChildRole');

        $roleName = $mediaList['roleName']->content;
        $roleAlias = $mediaList['roleAlias']->content;

        $parentRole = new BRole($parentRoleId);
        $role = $parentRole->addChild($roleName);

        $this->addRoleAlias($roleAlias, $role->getFullName());

        $this->onShowSpaceRoleList();
    }

    public function onShowRoleEventList() {

        $role = $this->getCurrentRole();
        $roleId = $role->getId();

        $view = $this->getRoleEventList($roleId);

        $this->updateControl->addRenderView('roleEventList', 'roleEventList', array(
            'roleEventList' => $view
        ));
    }

    public function onShowAddRoleEvent() {
        $space = Blyn::app()->getActiveSpace();
        $apps = $space->getApps();

        $eventListData = array();
        foreach ($apps as $appId => $app) {
            $eventTable = new BAEventSheet(NULL, NULL, $appId);
            $eventList = $eventTable->getView();
            $appClass = get_class($app);
            foreach ($eventList as $id => $event) {
                $eventData = array();
                $alias = $event->getItem('alias')->getValue();
                $name = $event->getItem('name')->getValue();
                $eventData['name'] = $name;
                $eventData['alias'] = $alias;
                $eventData['eventId'] = $id;
                $eventData['appClass'] = $appClass;
                $eventListData[$id] = $eventData;
            }
        }
        $this->updateControl->addRenderView('addRoleEvent', 'addRoleEvent', array(
            'eventList' => $eventList,
            'eventListData' => $eventListData
        ));
    }

    public function onAddRoleEvent() {

        $eventCooker = new BAEventCooker();
        $role = $this->getCurrentRole();
        $roleId = $role->getId();

        if (isset($_POST['BDynamicFormModel'])) {
            $checkedItems = $_POST['BDynamicFormModel'];

            foreach ($checkedItems as $id => $value) {
                $isChecked = $value['isChecked'];
                if ($isChecked) {
                    $eventId = $id;
                    $event = $eventCooker->getEvent($eventId);
                    $list = $this->addRoleEvent($roleId, $eventId);
                }
            }
        }

        $this->onShowRoleEventList();
    }

}
